const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CopyPlugin = require("copy-webpack-plugin");

const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");

// const DllReferencePlugin = require('webpack/lib/DllReferencePlugin');

const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");

const smp = new SpeedMeasurePlugin();

const isProduction = process.env.NODE_ENV === "production";

const { WebpackManifestPlugin } = require("webpack-manifest-plugin");
const paths = require("./paths");
const options = {
  fileName: "asset-manifest.json",
  publicPath: paths.publicUrlOrPath,
  generate: (seed, files, entrypoints) => {
    const manifestFiles = files.reduce((manifest, file) => {
      manifest[file.name] = file.path;
      return manifest;
    }, seed);
    const entrypointFiles = entrypoints.app.filter(
      (fileName) => !fileName.endsWith(".map")
    );

    return {
      files: manifestFiles,
      entrypoints: entrypointFiles,
    };
  },
};

module.exports = smp.wrap({
  // mode: "production",
  mode: 'development',
  // optimization: {
  //   usedExports: true,
  // },
  devtool: "source-map",
  devServer: {
    port: 3000,
    historyApiFallback: true,
  },
  context: __dirname,
  entry: {
    app: "./src/index.jsx",
    // test: './src/test.js' // 测试函数lazy parsing, eager parsing
  },
  output: {
    path: `${__dirname}/dist`,
    filename: "[name].[fullhash].bundle.js",
    chunkFilename: "[name].[chunkhash:8].bundle.js",
  },
  optimization: {
    // minimizer: [
    //   // For webpack@5 you can use the `...` syntax to extend existing minimizers (i.e. `terser-webpack-plugin`), uncomment the next line
    //   // `...`,
    //   new CssMinimizerPlugin(),
    // ],
    splitChunks: {
      cacheGroups: {
        vendor: {
          name: "vendor",
          test: /[\\/]node_modules[\\/]/,
          minSize: 0,
          minChunks: 1,
          priority: 10,
          chunks: "initial",
        },
        common: {
          name: "common",
          test: /[\\/]src[\\/]/,
          chunks: "all",
          minSize: 0,
          minChunks: 2,
        },
      },
    },
  },
  resolve: {
    extensions: [".js", ".jsx"],
  },

  plugins: [
    new webpack.DefinePlugin({
      "process.env.PUBLIC_URL": JSON.stringify(""),
    }),
    new HtmlWebpackPlugin({
      template: "template.html",
    }),
    new MiniCssExtractPlugin({
      filename: "[name].[contenthash].css",
      chunkFilename: "[id].[contenthash:8].css",
    }),

    new WebpackManifestPlugin(options),
  ],

  module: {
    rules: [
      {
        test: /.s?css$/,
        use: [MiniCssExtractPlugin.loader, "css-loader"],
      },
      { test: /\.ts$/, use: "ts-loader" },
      {
        test: /\.jsx?$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-env"],
          },
        },
      },
      {
        test: /\.(png|jpg|gif)$/i,
        dependency: { not: ["url"] },
        use: [
          {
            loader: "url-loader",
            options: {
              limit: 8192,
            },
          },
        ],
      },
    ],
  },
});
